package com.lekang.le.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.lekang.common.core.domain.entity.SysUser;
import com.lekang.common.utils.DateUtils;
import com.lekang.common.utils.SecurityUtils;
import com.lekang.le.domain.AccraditationRecord;
import com.lekang.le.domain.ElderlySzh;
import com.lekang.le.domain.PendingTasks;
import com.lekang.le.mapper.AccraditationRecordMapper;
import com.lekang.le.mapper.ElderlySzhMapper;
import com.lekang.le.mapper.PendingTasksMapper;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lekang.le.mapper.LeaveRequestMapper;
import com.lekang.le.domain.LeaveRequest;
import com.lekang.le.service.ILeaveRequestService;
import com.lekang.system.service.ISysUserService;

/**
 * 我的请假Service业务层处理
 * 
 * @author szh
 * @date 2025-10-15
 */
@Service
public class LeaveRequestServiceImpl implements ILeaveRequestService 
{
    @Autowired
    private LeaveRequestMapper leaveRequestMapper;
    @Autowired
    private AccraditationRecordMapper accraditationRecordMapper;
    @Autowired
    private PendingTasksMapper pendingTasksMapper;
    @Autowired
    private ElderlySzhMapper elderlyMapper; // 用于查询老人姓名
    @Autowired
    private ISysUserService sysUserService; // 若依用户服务，查询护理组组长
    // Flowable流程服务
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;

    /**
     * 根据老人ID和请假状态查询请假记录
     */
    @Override
    public List<LeaveRequest> selectByElderlyIdAndStatus(Long elderlyId, String leaveStatus) {
        return leaveRequestMapper.selectByElderlyIdAndStatus(elderlyId, leaveStatus);
    }

    /**
     * 检查老人是否处于请假中状态
     */
    @Override
    public boolean checkElderlyLeaveStatus(Long elderlyId) {
        List<LeaveRequest> leaveRequests = leaveRequestMapper.selectByElderlyIdAndStatus(elderlyId, "请假中");
        return leaveRequests != null && !leaveRequests.isEmpty();
    }
    /**
     * 查询我的请假
     * 
     * @param id 我的请假主键
     * @return 我的请假
     */
    @Override
    public LeaveRequest selectLeaveRequestById(Long id)
    {
        return leaveRequestMapper.selectLeaveRequestById(id);
    }

    /**
     * 查询我的请假列表
     * 
     * @param leaveRequest 我的请假
     * @return 我的请假
     */
    @Override
    public List<LeaveRequest> selectLeaveRequestList(LeaveRequest leaveRequest)
    {
        return leaveRequestMapper.selectLeaveRequestList(leaveRequest);
    }

    /**
     * 新增我的请假
     * 
     * @param leaveRequest 我的请假
     * @return 结果
     */
    @Override
    public int insertLeaveRequest(LeaveRequest leaveRequest)
    {
        // -------------------------- 步骤1：校验老人当前请假状态 --------------------------
        // 1.1 根据老人外键ID查询请假表，判断是否存在“请假中”的记录
        List<LeaveRequest> existingLeave = leaveRequestMapper.selectByElderlyIdAndStatus(
                leaveRequest.getElderlyId(), "请假中");
        if (existingLeave != null && !existingLeave.isEmpty()) {
            throw new RuntimeException("该老人当前处于请假中，无法重复提交请假申请");
        }

        // -------------------------- 步骤2：获取护理员信息并赋值请假数据 --------------------------
        // 2.1 通过若依SecurityUtils获取当前登录护理员（申请人）信息
        SysUser currentNurse = SecurityUtils.getLoginUser().getUser();
        Long nurseUserId = currentNurse.getUserId(); // 护理员user_id
        String nurseUserName = currentNurse.getNickName(); // 护理员姓名

        // 2.2 处理陪同人信息：若选择“无”，陪同人姓名/电话设为“0”
        String companionType = leaveRequest.getCompanionType();
        if ("无".equals(companionType)) {
            leaveRequest.setCompanionName("0");
            leaveRequest.setCompanionPhone("0");
        }

        // 2.3 赋值请假表基础字段
        leaveRequest.setCreateTime(DateUtils.getNowDate());
        leaveRequest.setCreator(nurseUserId); // 创建人（护理员user_id）
        leaveRequest.setLeaveStatus("请假中"); // 初始状态：0-待审批（根据实际枚举调整）
        // 插入请假记录，获取主键ID（需确保mapper的insert方法支持返回自增ID）
        int insertResult = leaveRequestMapper.insertLeaveRequest(leaveRequest);
        Long leaveId = leaveRequest.getId(); // 请假记录主键（业务ID）

        // -------------------------- 步骤3：设置流程节点办理人 --------------------------
        // 3.1 第一个节点办理人：当前护理员（assignee1 = 护理员user_id）
        String assignee1 = nurseUserId.toString();
        // 3.2 第二个节点办理人：查询护理组组长（若依角色关联查询）
        // 假设护理组组长角色标识为“ROLE_NURSE_LEADER”，查询该角色下的用户
        SysUser nurseLeader = sysUserService.selectUserByRoleId("huliyuanzuzhang"); // 需自定义该方法
        if (nurseLeader == null) {
            throw new RuntimeException("未配置护理组组长，请联系管理员");
        }
        //String assignee2 = nurseLeader.getUserId().toString(); // 护理组组长user_id
        String assignee2 = nurseLeader.getUserId().toString();
        String leaderUserName = nurseLeader.getNickName(); // 护理组组长姓名

        // -------------------------- 步骤4：创建流程实例并绑定businessKey --------------------------
        // 4.1 流程变量：设置两个节点的办理人
        Map<String, Object> processVars = new HashMap<>();
        processVars.put("assignee1", assignee1);
        processVars.put("assignee2", assignee2);
        // 4.2 启动流程（流程定义key为“qingjia”，与bpmn文件中process id一致）
        // businessKey = 请假记录ID（关联业务数据与流程）
        runtimeService.startProcessInstanceByKey("qingjia", leaveId.toString(), processVars);

        // -------------------------- 步骤5：完成“护理员填写请假单”节点 --------------------------
        // 5.1 查询当前流程实例下，护理员的待办任务（节点ID：sid-b731d094-580b-444a-bbd7-063a30117e9d）
        Task nurseTask = taskService.createTaskQuery()
                .processInstanceBusinessKey(leaveId.toString())
                .taskAssignee(assignee1)
                .taskDefinitionKey("sid-b731d094-580b-444a-bbd7-063a30117e9d")
                .singleResult();
        if (nurseTask == null) {
            throw new RuntimeException("未查询到护理员填写请假单的流程任务");
        }
        // 5.2 完成护理员节点（流转到组长审批节点）
        taskService.complete(nurseTask.getId());

        // -------------------------- 步骤6：保存护理员的审批记录 --------------------------
        ElderlySzh elderly = elderlyMapper.selectElderlyById(leaveRequest.getElderlyId());
        String title = elderly.getName() + "请假申请"; // 标题：xxx老人请假申请
        AccraditationRecord nurseRecord = new AccraditationRecord();
        nurseRecord.setType(2L); // 类型：2-请假（与pending_tasks表type一致）
        nurseRecord.setBussniessId(leaveId); // 业务ID：请假记录ID
        nurseRecord.setApproverId(nurseUserId); // 审批人ID：护理员user_id
        nurseRecord.setApproverName(nurseUserName); // 审批人姓名：护理员姓名
        nurseRecord.setApproverNameRole("护理员"); // 审批人角色
        nurseRecord.setCurrentStep("护理员填写请假单"); // 当前步骤
        nurseRecord.setNextStep("护理组组长审批"); // 下一步骤
        nurseRecord.setNextApproverId(nurseLeader.getUserId()); // 下一个审批人ID
        nurseRecord.setNextApprover(leaderUserName); // 下一个审批人姓名
        nurseRecord.setNextApproverRole("护理组组长"); // 下一个审批人角色
        nurseRecord.setAuditStatus(1L); // 审核状态：1-已提交（待组长审批）
        nurseRecord.setStepNo(0L); // 审核步骤：0（第一步）
        nurseRecord.setCreateTime(DateUtils.getNowDate());
        nurseRecord.setCreateBy(nurseUserId.toString());
        nurseRecord.setFinishTime(DateUtils.getNowDate());
        nurseRecord.setExtraField1(title);
        nurseRecord.setHandleType(1L);
        accraditationRecordMapper.insertAccraditationRecordSZH(nurseRecord); // 插入审批记录

        /*// -------------------------- 步骤7：保存护理员的操作到待办任务表（已办） --------------------------
        // 7.1 查询老人姓名（用于title）
        ElderlySzh elderly = elderlyMapper.selectElderlyById(leaveRequest.getElderlyId());
        String title = elderly.getName() + "请假申请"; // 标题：xxx老人请假申请

        PendingTasks nursePending = new PendingTasks();
        nursePending.setBussniessId(leaveId); // 业务ID：请假记录ID
        nursePending.setTaskId(nurseTask.getId()); // 流程任务ID
        nursePending.setTitle(title);
        nursePending.setType(2L); // 类型：2-请假
        nursePending.setAssignee(nurseUserName); // 操作人：护理员姓名
        nursePending.setAssigneeId(nurseUserId); // 操作人ID：护理员user_id
        nursePending.setStatus(1L); // 状态：1-申请中
        nursePending.setApplicationTime(DateUtils.getNowDate()); // 申请时间
        nursePending.setApplicat(nurseUserName); // 申请人
        nursePending.setApplicatId(nurseUserId); // 申请人ID
        nursePending.setIsHandle(1L); // 是否处理：1-已处理（护理员已完成填写）
        nursePending.setStepNo(0L); // 步骤：0
        nursePending.setCreateTime(DateUtils.getNowDate());
        nursePending.setFinishTime(DateUtils.getNowDate());
        pendingTasksMapper.insertPendingTasksSZH(nursePending); // 插入护理员已办任务*/

        // -------------------------- 步骤7：保存护理组组长的待办任务 --------------------------
        // 8.1 查询组长审批节点的任务（节点ID：sid-45279e53-2318-4a57-a409-e72b2ea8e15f）
        Task leaderTask = taskService.createTaskQuery()
                .processInstanceBusinessKey(leaveId.toString())
                .taskAssignee(assignee2)
                .taskDefinitionKey("sid-45279e53-2318-4a57-a409-e72b2ea8e15f")
                .singleResult();
        if (leaderTask == null) {
            throw new RuntimeException("未查询到护理组组长审批的流程任务");
        }

        PendingTasks leaderPending = new PendingTasks();
        leaderPending.setBussniessId(leaveId); // 业务ID：请假记录ID
        leaderPending.setTaskId(leaderTask.getId()); // 组长审批任务ID
        leaderPending.setTitle(title); // 同步骤7的标题
        leaderPending.setType(2L); // 类型：2-请假
        leaderPending.setAssignee(leaderUserName); // 操作人：组长姓名
        leaderPending.setAssigneeId(nurseLeader.getUserId()); // 操作人ID：组长user_id
        leaderPending.setStatus(1L); // 状态：1-申请中
        leaderPending.setApplicationTime(DateUtils.getNowDate()); // 申请时间
        leaderPending.setApplicat(nurseUserName); // 申请人：护理员
        leaderPending.setApplicatId(nurseUserId); // 申请人ID：护理员user_id
        leaderPending.setIsHandle(0L); // 是否处理：0-未处理（待组长审批）
        leaderPending.setStepNo(1L); // 步骤：1（第二步）
        leaderPending.setCreateTime(DateUtils.getNowDate());
        pendingTasksMapper.insertPendingTasksSZH(leaderPending); // 插入组长待办任务
        return insertResult;

        /*leaveRequest.setCreateTime(DateUtils.getNowDate());
        return leaveRequestMapper.insertLeaveRequest(leaveRequest);*/
    }

    /**
     * 修改我的请假
     * 
     * @param leaveRequest 我的请假
     * @return 结果
     */
    @Override
    public int updateLeaveRequest(LeaveRequest leaveRequest)
    {
        return leaveRequestMapper.updateLeaveRequest(leaveRequest);
    }

    /**
     * 批量删除我的请假
     * 
     * @param ids 需要删除的我的请假主键
     * @return 结果
     */
    @Override
    public int deleteLeaveRequestByIds(Long[] ids)
    {
        return leaveRequestMapper.deleteLeaveRequestByIds(ids);
    }

    /**
     * 删除我的请假信息
     * 
     * @param id 我的请假主键
     * @return 结果
     */
    @Override
    public int deleteLeaveRequestById(Long id)
    {
        return leaveRequestMapper.deleteLeaveRequestById(id);
    }
}
